﻿using FreeSql;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LogExtensions
{
    public class LogConfigure
    {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="serviceProvider"></param>
        /// <param name="logger"></param>
        /// <exception cref="Exception"></exception>
        public static void ConfigureSerilog(HostBuilderContext context, IServiceProvider serviceProvider, LoggerConfiguration logger)
        {
           
            var logConfig = (serviceProvider.CreateScope().ServiceProvider.GetRequiredService<IOptions<DbConfig>>().Value).HttpLog;

            var loggerConfiguration = logger.ReadFrom.Configuration(context.Configuration)
                 .ReadFrom.Services(serviceProvider)
                .Enrich.FromLogContext();
        
            if (logConfig != null && logConfig.Shows.Any(x => x == LogShows.Console))
            {
                loggerConfiguration.WriteTo.Console(outputTemplate: "{Timestamp:HH:mm:ss} || {Level} || {IpAddress} || {Message} || {Exception} ||end {NewLine}");
            }
            if (logConfig != null && logConfig.Shows.Any(x => x == LogShows.File))
            {
                loggerConfiguration.WriteTo.File($"{AppContext.BaseDirectory}Logs/.log", rollingInterval: RollingInterval.Day,
                      rollOnFileSizeLimit: true, fileSizeLimitBytes: 50485760,
                    outputTemplate: "{Timestamp:HH:mm:ss} || {RequestPath} || {Level} || {IpAddress} || {Message} || {Exception} ||end {NewLine}");
            }
            if (logConfig != null && logConfig.Shows.Any(x => x == LogShows.DataBase))
            {
                var dbconfig = serviceProvider.CreateScope().ServiceProvider.GetRequiredService<IOptions<DbConfig>>().Value;
                loggerConfiguration.WriteTo.Map(keyPropertyName: "Name",
                         defaultKey: "0",
                   configure: (name, wt) =>
                   {
                       wt.Async(lc => lc.FsqlSink(
                        options: new Serilog.Sinks.Fsql.FreeSqlSinkOptions
                        {
                            ConnectionString = dbconfig.ConnectionString,
                            ColumnNameStyle = (int)FreeSql.Internal.NameConvertType.PascalCaseToUnderscoreWithLower,
                            DataType = dbconfig.DataType,
                            EnableShard = false,
                            TableName = $"log_{name}",
                            ShardReserveTableDay = 30,
                        }, new Serilog.Sinks.PeriodicBatching.PeriodicBatchingSinkOptions
                        {
                            BatchSizeLimit = 1000,
                            EagerlyEmitFirstEvent = true,
                            QueueLimit = 100,
                        }),
                        100, true);
                   });
                 
            }

        }
    }
}
